/*
 * main.cpp
 *
 *  Created on: 19/05/2010
 *      Author: Nadav
 */

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "scene_parser.h"
#include "camera.h"
#include "vectors.h"
#include "group.h"
#include "image.h"

char *input_file = NULL;
int width = 100;
int height = 100;
char *output_file = NULL;
float depth_min = 0;
float depth_max = 1;
char *depth_file = NULL;

// sample command lines:
// raycast -input input.txt -size 100 100 -output output.tga
// raycast -input input.txt -size 100 100 -depth 5.5 8.8 output.tga


void parseArgs(int argc, char** argv) {
	for (int i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-input")) {
			i++;
			assert(i < argc);
			input_file = argv[i];
		} else if (!strcmp(argv[i], "-size")) {
			i++;
			assert(i < argc);
			width = atoi(argv[i]);
			i++;
			assert(i < argc);
			height = atoi(argv[i]);
		} else if (!strcmp(argv[i], "-output")) {
			i++;
			assert(i < argc);
			output_file = argv[i];
		} else if (!strcmp(argv[i], "-depth")) {
			i++;
			assert(i < argc);
			depth_min = atof(argv[i]);
			i++;
			assert(i < argc);
			depth_max = atof(argv[i]);
			i++;
			assert(i < argc);
			depth_file = argv[i];
		} else {
			printf("whoops error with command line argument %d: '%s'\n", i,
					argv[i]);
			assert(0);
		}
	}
}

void render(SceneParser& scene) {
	Camera* camera = scene.getCamera();
	Vec3f background = scene.getBackgroundColor();
	Group* group = scene.getGroup();

	Image imgColor(width, height);
	Image imgDepth(width, height);
	imgColor.SetAllPixels(background);
	float tmin = -9999;
	for (int w=0; w<width; ++w) {
		for (int h=0; h<height; ++h) {
			Vec2f point((float)w/(float)width, (float)h/(float)height);
			Ray ray = camera->generateRay(point);
			Hit hit(9999, background, Vec3f());
			group->intersect(ray, hit, tmin);
			if (hit.getT()>tmin && hit.getT()<9999) {
				imgColor.SetPixel(w,h,hit.getColor());
				float color = 1- ((hit.getT()-depth_min) / (depth_max - depth_min));
				Vec3f colorVec(color,color,color);
				imgDepth.SetPixel(w,h,colorVec);
			}
		}
	}
	imgColor.SaveTGA(output_file);
	imgDepth.SaveTGA(depth_file);
}


int main(int argc, char** argv) {
	parseArgs(argc, argv);
	SceneParser scene(input_file);
	render(scene);
//	renderByDepth(scene);
	return 0;
}
